using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Principal;
using System.Security.AccessControl;
using System.Diagnostics;
using CPGVertragsverwaltung.ErrorHandling;
using System.Data;
using CPGVertragsverwaltung.DatabaseAccess;
using System.Windows.Forms;

namespace CPGVertragsverwaltung.SecurityController
{
    class PermissionServices
    {
        public static void setFolderSecurity(String pContractID, SecurityObjectPermissionCollection pSecurityObjects)
        {
            String folderPath = GlobalFunctions.getAttachmentFolder(pContractID);
            DirectorySecurity folderSec = Directory.GetAccessControl(folderPath);

            //Check if Exists
            if (!Directory.Exists(folderPath))
            {
                return;
            }


            //Remove old SecurityObjects            
            foreach (FileSystemAccessRule testRule in folderSec.GetAccessRules(true, true, typeof(NTAccount)))
            {
                if (testRule.IdentityReference.Translate(typeof(SecurityIdentifier)).Value != GlobalVariables.ADAdminGroupSID)
                {
                    folderSec.RemoveAccessRule(testRule);
                }
            }

            //Add new SecurityObjects
            foreach (SecurityObjectPermission SecurityObject in pSecurityObjects)
            {
                String SID = SecurityObject.SID;
                Boolean canRead = SecurityObject.canRead;
                Boolean canWrite = SecurityObject.canWrite;

                SecurityIdentifier mySID = new SecurityIdentifier(SID);

                //Only Change if it is not Admin
                if (mySID.ToString() != GlobalVariables.ADAdminGroupSID)
                {
                    //folder Permissions
                    FileSystemRights fsRights = FileSystemRights.ListDirectory;
                    if (canRead)
                        fsRights = FileSystemRights.Read;
                    if (canWrite)
                        fsRights = FileSystemRights.Read | FileSystemRights.Write;

                    FileSystemAccessRule fsRule = new FileSystemAccessRule(mySID, fsRights, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow);
                    folderSec.SetAccessRule(fsRule);
                    Directory.SetAccessControl(folderPath, folderSec);
                }
            }

        }

        /// <summary>
        /// Create Folder and set Permission
        /// </summary>
        /// <param name="pContractID"></param>
        public static void checkContractFolder(String pContractID)
        {
            String mFolderPath = GlobalFunctions.getAttachmentFolder(pContractID);
            if (!Directory.Exists(mFolderPath))
            {
                DirectoryInfo DirInfo = null;
                try
                {
                    DirInfo = Directory.CreateDirectory(mFolderPath);
                }
                catch (Exception ex)
                {
                    MessageHandling.showError("Ordner konnte nicht erstellt werden '" + mFolderPath + "'", true);
                }

                //Set Security Settings
                SecurityIdentifier adminSID = new SecurityIdentifier(GlobalVariables.ADAdminGroupSID);
                DirectorySecurity folderSec = Directory.GetAccessControl(mFolderPath);

                //Remove Inheritance
                folderSec.SetAccessRuleProtection(true, false);

                //Add CPG_Admin for Full Control
                FileSystemAccessRule fsRule = new FileSystemAccessRule(adminSID, FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow);
                folderSec.SetAccessRule(fsRule);
                Directory.SetAccessControl(mFolderPath, folderSec);
            }
        }

        /// <summary>
        /// Check if User has Permission to Read this Contract
        /// </summary>
        /// <param name="pCotnractID"></param>
        /// <returns></returns>
        public static Boolean checkContractReadPermission(int pCotnractID)
        {
            int canRead = -1;   //doesn't defined --> will be false at the End

            String SQLSelect = "SELECT * FROM vertragpermission WHERE vertragpermission_vertragid =" + pCotnractID + " AND (vertragpermission_sid='" + WindowsIdentity.GetCurrent().User.ToString() + "'";
            IdentityReferenceCollection currentGroups = WindowsIdentity.GetCurrent().Groups;
            if (currentGroups.Count > 0)
            {
                SQLSelect += " OR ";
            }
            for(int i=0;i<currentGroups.Count;i++)
            {
                IdentityReference tempID = currentGroups[i];
                String tempSID = tempID.ToString();
                SQLSelect += " vertragpermission_sid='" + tempID + "'";
                if (i < currentGroups.Count - 1)
                {
                    SQLSelect += " OR ";
                }
            }
            SQLSelect += ")";

            //Load Data From Database
            DataTable myDataTable = DBProvider.doSQLSelect(SQLSelect);
            foreach (DataRow myRow in myDataTable.Rows)
            {
                Boolean tempCanRead = DBUtilities.getBooleanFromRow(myRow, "vertragpermission_read");
                if (tempCanRead)
                {
                        canRead = 1;
                }
                else
                {
                    if (canRead != 1)
                    {
                        canRead = 0;
                    }
                }
                Application.DoEvents();
            }

            if (canRead == 1 || GlobalVariables.UserIsAdmin)
            {
                return true;
            }
            else
            {
                return false;
            }


        }

        /// <summary>
        /// Check if User has Permission to Modify this Contract
        /// </summary>
        /// <param name="pCotnractID"></param>
        /// <returns></returns>
        public static Boolean checkContractWritePermission(int pCotnractID)
        {
            int canWrite = -1;   //doesn't defined --> will be false at the End

            String SQLSelect = "SELECT * FROM vertragpermission WHERE vertragpermission_vertragid =" + pCotnractID + " AND (vertragpermission_sid='" + WindowsIdentity.GetCurrent().User.ToString() + "'";
            IdentityReferenceCollection currentGroups = WindowsIdentity.GetCurrent().Groups;
            if (currentGroups.Count > 0)
            {
                SQLSelect += " OR ";
            }
            for (int i = 0; i < currentGroups.Count; i++)
            {
                IdentityReference tempID = currentGroups[i];
                String tempSID = tempID.ToString();
                SQLSelect += " vertragpermission_sid='" + tempID + "'";
                if (i < currentGroups.Count - 1)
                {
                    SQLSelect += " OR ";
                }
            }
            SQLSelect += ")";

            //Load Data From Database
            DataTable myDataTable = DBProvider.doSQLSelect(SQLSelect);
            foreach (DataRow myRow in myDataTable.Rows)
            {
                Boolean tempCanWrite = DBUtilities.getBooleanFromRow(myRow, "vertragpermission_modify");
                if (tempCanWrite)
                {
                        canWrite = 1;
                }
                else
                {
                    if (canWrite != 1)
                    {
                        canWrite = 0;
                    }
                }
                Application.DoEvents();
            }

           
            if (canWrite == 1 || GlobalVariables.UserIsAdmin)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

    }
}
